#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "clientList.h"


void *fun(void *arg)
{
	struct clientfds *p = (struct clientfds *)arg;

	int ret = 0;
	char buf[1024] = {0};
	while(1)
	{
		memset(buf,0,1024);
		ret = recv(p->fd,buf,1023,0);
		if(ret <= 0)
		{
			perror("recv");
			pthread_exit(NULL);
		}

		if(strcmp(buf,"heartbit") == 0)
		{
			p->count = 0;
			printf("%s 发送心跳包\n",p->ipaddr);
		}else
		{
			printf("buf is %s\n",buf);
			p->count = 0;
		}
			
	}

	pthread_exit(0);

}


void *heartfun(void *arg)
{
	struct clientfds *head = (struct clientfds *)arg;
	struct clientfds *p = NULL;

	while(1)
	{
		sleep(3);
		p = head->next;
		while(p != NULL)
		{
			p->count = p->count + 1;
			printf("%d:%d\n",p->fd,p->count);
			if(p->count == 5)
			{
				printf("%s is leaving\n",p->ipaddr);
				close(p->fd);
				pthread_cancel(p->pid);
				delete_by_fd(head,p->fd);
			}
			p = p->next;
		}
	}
}



int create_socket(void)
{
	int fd = 0;
	int sockfd = 0;
	int ret = 0;
	struct sockaddr_in  addr;

	memset(&addr,0,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = 6868;
	addr.sin_addr.s_addr = inet_addr("192.168.0.146");

	fd = socket(AF_INET,SOCK_STREAM,0);
	if(fd < 0)
	{
		perror("socket");
		exit(-1);
	}


	ret = bind(fd,(struct sockaddr *)&addr,sizeof(struct sockaddr));
	if(ret < 0)
	{
		perror("bind");
		exit(-1);
	}

	ret = listen(fd,5);
	if(ret < 0)
	{
		perror("listen");
		exit(-1);
	}

	return fd;
}


int main()
{
	int fd = 0;
	int len = 0;
	struct sockaddr_in cliaddr;
	int sockfd = 0;

	struct clientfds *head = NULL;
	struct clientfds *p = NULL;
	struct clientfds data;

	memset(&data,0,sizeof(data));
	memset(&cliaddr,0,sizeof(cliaddr));
	len = sizeof(struct sockaddr);
	memset(&data,0,sizeof(data));

	fd = create_socket();

	head = create_clientfds();

	pthread_t pid = 0;
	pthread_t pid_heart = 0;
	int ret = 0;

	ret = pthread_create(&pid_heart,NULL,heartfun,head);
	if(ret != 0)
	{
		perror("pthread_create error");
		exit(-1);
	}
	


	while(1)
	{
		sockfd = accept(fd,(struct sockaddr*)&cliaddr,&len);
		if(sockfd < 0)
		{
			perror("accept");
			exit(-1);
		}

		data.fd = sockfd;
		strcpy(data.ipaddr,inet_ntoa(cliaddr.sin_addr));
		data.count = 0;

		p = insert(head,data);

		ret = pthread_create(&(p->pid),NULL,fun,p);
		if(ret != 0)
		{
			perror("pthread_create");
			exit(-1);
		}

	}

	close(fd);

	return 0;
}
